import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'dart:ui' as ui;
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

abstract class ISuspensionBean {
  bool isShowSuspension = false;

  String getSuspensionTag();
}

class SuspensionUtil {
  /// 根据[A-Z]排序。
  static void sortListBySuspensionTag(List<ISuspensionBean>? list) {
    if (list == null || list.isEmpty) return;
    list.sort((a, b) {
      if (a.getSuspensionTag() == "@" || b.getSuspensionTag() == "#") {
        return -1;
      } else if (a.getSuspensionTag() == "#" || b.getSuspensionTag() == "@") {
        return 1;
      } else {
        return a.getSuspensionTag().compareTo(b.getSuspensionTag());
      }
    });
  }

  /// 获取索引列表。
  static List<String> getTagIndexList(List<ISuspensionBean>? list) {
    List<String> indexData = [];
    if (list != null && list.isNotEmpty) {
      String? tempTag;
      for (int i = 0, length = list.length; i < length; i++) {
        String tag = list[i].getSuspensionTag();
        if (tempTag != tag) {
          indexData.add(tag);
          tempTag = tag;
        }
      }
    }
    return indexData;
  }

  /// 设置显示悬停Header状态。
  static void setShowSuspensionStatus(List<ISuspensionBean>? list) {
    if (list == null || list.isEmpty) return;
    String? tempTag;
    for (int i = 0, length = list.length; i < length; i++) {
      String tag = list[i].getSuspensionTag();
      if (tempTag != tag) {
        tempTag = tag;
        list[i].isShowSuspension = true;
      } else {
        list[i].isShowSuspension = false;
      }
    }
  }
}

class NullCheckUtils {
  static bool isNullOrEmpty<T>(T? value) {
    if (value == null) {
      return true;
    } else if (value is String) {
      return (value as String).isEmpty;
    } else if (value is Iterable) {
      return (value as Iterable).isEmpty;
    } else if (value is Map) {
      return (value as Map).isEmpty;
    } else {
      return false;
    }
  }
}

class ClickUtils {
  static bool _isButtonDisabled = false;

  static Future<void> onClick(Function callback) async {
    if (!_isButtonDisabled) {
      _isButtonDisabled = true;
      await callback();
      await Future.delayed(const Duration(seconds: 1));
      _isButtonDisabled = false;
    }
  }
}

class StringUtils {
  static int calculateDuration(int textLength) {
    const int charactersPerSecond = 5;
    int duration = (textLength / charactersPerSecond).ceil();
    return duration;
  }
}

final GlobalKey boundaryKey = GlobalKey();

class PhotoUtils {
  static late BuildContext mContext;

  static Future<String> captureImage() async {
    RenderRepaintBoundary? boundary = boundaryKey.currentContext!
        .findRenderObject() as RenderRepaintBoundary?;
    double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比
    var image = await boundary!.toImage(pixelRatio: dpr);
    // 将image转化成byte
    ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);

    var filePath = "";

    Uint8List pngBytes = byteData!.buffer.asUint8List();
    // 获取手机存储（getTemporaryDirectory临时存储路径）
    Directory applicationDir = await getTemporaryDirectory();
    // getApplicationDocumentsDirectory();
    // 判断路径是否存在
    bool isDirExist = await Directory(applicationDir.path).exists();
    if (!isDirExist) Directory(applicationDir.path).create();
    // 直接保存，返回的就是保存后的文件
    File saveFile = await File(
        "${applicationDir.path}${DateTime.now().toIso8601String()}.jpg")
        .writeAsBytes(pngBytes);
    filePath = saveFile.path;
    return filePath;
  }

  //保存到相册
  static void savePhoto(BuildContext context, String backgroundImage) async {
    mContext = context;
    RenderRepaintBoundary? boundary = boundaryKey.currentContext!
        .findRenderObject() as RenderRepaintBoundary?;
    double dpr = ui.window.devicePixelRatio;
    var image = await boundary!.toImage(pixelRatio: dpr);

    //获取保存相册权限，如果没有，则申请改权限
    bool permition = await _checkAndRequestPermissions();
    if (permition) {
      EasyLoading.show();
      ui.Image imageWithBackground =
      await _addWhiteBackgroundToImage(image, backgroundImage);
      // 将image转化成byte
      ByteData? byteData =
      await imageWithBackground.toByteData(format: ImageByteFormat.png);
      EasyLoading.dismiss();
      Uint8List images = byteData!.buffer.asUint8List();

      final result = await ImageGallerySaver.saveImage(images, quality: 100);
      if (result != null) {
        EasyLoading.showSuccess("图片保存成功");
      } else {
        EasyLoading.showError("图片保存失败");
      }
    }
  }

  static void onShare(
      BuildContext context, String bacPhoto, Function function) async {
    mContext = context;
    RenderRepaintBoundary? boundary = boundaryKey.currentContext!
        .findRenderObject() as RenderRepaintBoundary?;
    double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比
    var image = await boundary!.toImage(pixelRatio: dpr);

    EasyLoading.show();
    ui.Image imageWithBackground =
    await _addWhiteBackgroundToImage(image, bacPhoto);
    // 将image转化成byte
    ByteData? byteData =
    await imageWithBackground.toByteData(format: ImageByteFormat.png);
    EasyLoading.dismiss();
    Uint8List images = byteData!.buffer.asUint8List();
    function.call(images);
  }

  static Future<ui.Image> _addWhiteBackgroundToImage(
      ui.Image inputImage, String backgroundPhoto) async {
    // 获取原始图片的宽度和高度
    int originalWidth = inputImage.width;
    int originalHeight = inputImage.height;
    // 计算新的宽度和高度（1.5倍）
    int newWidth = (originalWidth * 1.5).toInt();
    int newHeight = (originalHeight * 1.5).toInt();

    // 创建一个新的图片（包括背景图）
    ui.PictureRecorder recorder = ui.PictureRecorder();
    Canvas canvas = Canvas(recorder);

    // 本地图片路径（请替换为实际路径）
    String backgroundImagePath = backgroundPhoto;

    // 加载本地图片
    final ByteData data = await rootBundle.load(backgroundImagePath);
    final List<int> bytes = data.buffer.asUint8List();
    ui.Codec codec = await ui.instantiateImageCodec(Uint8List.fromList(bytes));
    ui.FrameInfo frameInfo = await codec.getNextFrame();
    ui.Image backgroundImage = frameInfo.image;

    // 将背景图片绘制到新的图片上，并添加四个角的圆角
    Paint backgroundPaint = Paint();
    Rect backgroundRect = Rect.fromPoints(
        const Offset(0, 0), Offset(newWidth.toDouble(), newHeight.toDouble()));
    RRect backgroundRRect =
    RRect.fromRectAndRadius(backgroundRect, const Radius.circular(20.0));
    canvas.drawRRect(backgroundRRect, backgroundPaint);
    canvas.drawImageRect(
      backgroundImage,
      Rect.fromPoints(
          Offset(0, 0),
          Offset(backgroundImage.width.toDouble(),
              backgroundImage.height.toDouble())),
      backgroundRect,
      backgroundPaint,
    );

    // 将原始图片绘制到新的图片上，并按1.5倍比例缩放
    Paint imagePaint = Paint();
    Rect srcRect = Rect.fromPoints(const Offset(0, 0),
        Offset(originalWidth.toDouble(), originalHeight.toDouble()));
    Rect destRect = Rect.fromPoints(
      const Offset(0, 0),
      Offset(newWidth.toDouble(), newHeight.toDouble()),
    );
    canvas.drawImageRect(inputImage, srcRect, destRect, imagePaint);
    // 完成录制
    ui.Picture picture = recorder.endRecording();
    ui.Image outputImage = await picture.toImage(newWidth, newHeight);

    return outputImage;
  }

  ///申请存本地相册权限
  static Future<bool> _checkAndRequestPermissions() async {
    if (Platform.isIOS) {
      var status = await Permission.photos.status;
      if (status.isDenied) {
        Map<Permission, PermissionStatus> statuses =
        await [Permission.photos].request();
        return statuses[Permission.photos]!.isGranted;
      } else {
        _showSettingsDialog();
        return false;
      }
    } else {
      DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
      AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;

      if (androidInfo.version.sdkInt >= 30) {
        List<Permission> permissions = [
          Permission.videos,
          Permission.audio,
          Permission.storage
        ];
        Map<Permission, PermissionStatus> statuses =
        await permissions.request();
        bool allGranted = statuses.values.every((status) => status.isGranted);

        if (allGranted) {
          return true;
        } else {
          bool isDenied = statuses.values.any((status) => status.isDenied);
          if (isDenied) {
            statuses = await permissions.request();
            return statuses.values.every((status) => status.isGranted);
          } else {
            _showSettingsDialog();
            return false;
          }
        }
      } else {
        var storageStatus = await Permission.storage.status;
        if (storageStatus.isGranted) {
          return true;
        } else if (storageStatus.isPermanentlyDenied) {
          _showSettingsDialog();
          return false;
        } else {
          PermissionStatus status = await Permission.storage.request();
          if (status.isGranted) {
            return true;
          } else {
            _showSettingsDialog();
            return false;
          }
        }
      }
    }
  }

  static Future<bool> _checkAndRequestCameraPermissions() async {
    if (Platform.isIOS) {
      var status = await Permission.camera.status;
      if (status.isDenied) {
        Map<Permission, PermissionStatus> statuses =
        await [Permission.camera].request();
        return statuses[Permission.camera]!.isGranted;
      } else {
        _showSettingsDialog();
        return false;
      }
    } else {
      var storageStatus = await Permission.camera.status;
      if (storageStatus.isGranted) {
        return true;
      } else if (storageStatus.isPermanentlyDenied) {
        _showSettingsDialog();
        return false;
      } else {
        PermissionStatus status = await Permission.camera.request();
        if (status.isGranted) {
          return true;
        } else {
          _showSettingsDialog();
          return false;
        }
      }
    }
  }

  static void _showSettingsDialog() {
    showDialog(
      context: mContext,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('温馨提示'),
          content: const Text('检测当前您没有存储权限，请手动授予相关权限'),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: const Text('取消'),
            ),
            TextButton(
              onPressed: () {
                Navigator.pop(context);
                openAppSettings();
              },
              child: const Text('确定'),
            ),
          ],
        );
      },
    );
  }

  static Future<String?> saveImage(Uint8List imageData) async {
    try {
      bool permition = await _checkAndRequestPermissions();
      if (permition) {
        EasyLoading.show(status: '图片保存中...');
        final result =
        await ImageGallerySaver.saveImage(imageData, quality: 100);
        EasyLoading.dismiss();
        if (result != null) {
          EasyLoading.showSuccess("图片保存成功");
        } else {
          EasyLoading.showError('图片保存失败');
        }
      }
    } catch (e) {
      EasyLoading.showError("图片保存错误");
    }
  }

  static Future<String?> openImagePicker() async {
    try {
      bool permition = await _checkAndRequestPermissions();
      if (permition) {
        final picker = ImagePicker();
        final pickedFile = await picker.pickImage(source: ImageSource.gallery);
        if (pickedFile != null && pickedFile.path.isNotEmpty == true) {
          return pickedFile.path;
        }
        return "";
      }
    } catch (e) {
      return "";
    }
  }

  static Future<String?> openImageCamerPicker() async {
    try {
      bool permition = await _checkAndRequestCameraPermissions();
      if (permition) {
        final picker = ImagePicker();
        final pickedFile = await picker.pickImage(source: ImageSource.camera);
        if (pickedFile != null && pickedFile.path.isNotEmpty == true) {
          return pickedFile.path;
        }
        return "";
      }
    } catch (e) {
      return "";
    }
  }
}
